package com.upcode.weighing.detect.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.upcode.weighing.detect.service.DetectStatsService;
import com.upcode.weighing.domain.DetectRecord;
import com.upcode.weighing.mapper.DetectRecordMapper;
import com.upcode.weighing.util.DateUtils;
import com.upcode.weighing.util.NumberUtil;
import com.upcode.weighing.vo.DetectOverTypeStats;
import com.upcode.weighing.vo.req.DetectStatsQueryParam;
import com.upcode.weighing.vo.resp.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author alex
 * @since 2024-07-21
 */
@Service
public class DetectStatsServiceImpl extends ServiceImpl<DetectRecordMapper, DetectRecord> implements DetectStatsService {
    @Autowired
    private DetectRecordMapper detectRecordMapper;

    @Override
    public DetectOverviewStats overviewStats(DetectStatsQueryParam vo) {
        List<DetectOverTypeStats> detectOverTypeStatsList = detectRecordMapper.queryOverTypeStats(vo);
        Long detectTotal=0l;
        Long overDetectTotal=0l;
        Long notOverDetectTotal=0l;
        DetectOverviewStats detectOverviewStats=new DetectOverviewStats();
        for(DetectOverTypeStats detectOverTypeStats:detectOverTypeStatsList){
            detectTotal+=detectOverTypeStats.getDetectNum();
            if(detectOverTypeStats.getOverType()>DetectOverTypeStats.OVER_TYPE_NOT){
                overDetectTotal+=detectOverTypeStats.getDetectNum();
            }
        }
        if(detectTotal>0){
            notOverDetectTotal=detectTotal-overDetectTotal;
            Double finalOverDetectTotal = Double.valueOf(overDetectTotal);
            Double finalDetectTotal = Double.valueOf(detectTotal);
            List<DetectOverTypeStats> newStatsList = detectOverTypeStatsList.stream().map(item -> {
                if(item.getOverType()>DetectOverTypeStats.OVER_TYPE_NOT && finalOverDetectTotal>0){
                    item.setOverRatio(NumberUtil.halfUp(item.getDetectNum() / finalOverDetectTotal* 100,2) );
                }
                item.setTotalRatio(NumberUtil.halfUp(item.getDetectNum() / finalDetectTotal* 100,2) );
                return item;
            }).collect(Collectors.toList());

            detectOverviewStats.setOverDetectTotal(overDetectTotal);
            detectOverviewStats.setNotOverDetectTotal(notOverDetectTotal);
            if(finalDetectTotal>0){
                detectOverviewStats.setOverDetectRatio(NumberUtil.halfUp(finalOverDetectTotal/finalDetectTotal*100,2));
                detectOverviewStats.setNotOverDetectRatio(100-detectOverviewStats.getOverDetectRatio());
            }
            detectOverviewStats.setOverTypeStatsList(newStatsList);
        }
        detectOverviewStats.setDetectTotal(detectTotal);
        return detectOverviewStats;
    }

    @Override
    public List<VehicleTypeStats> vehTypeStats(DetectStatsQueryParam vo) {
        List<VehicleTypeStats>  vehicleTypeStatsList=detectRecordMapper.queryVehTypeStats(vo);
        double total=0;
        for(VehicleTypeStats vehicleTypeStats:vehicleTypeStatsList){
            total+=vehicleTypeStats.getNumber();
        }
        for(VehicleTypeStats vehicleTypeStats:vehicleTypeStatsList){
            vehicleTypeStats.setRatio(NumberUtil.halfUp(vehicleTypeStats.getNumber()/total*100,2));
        }
        return vehicleTypeStatsList;
    }

    @Override
    public Map<String,Object> tendencyStats(DetectStatsQueryParam vo) {
        List<TendencyStats>  tendencyStatsList=null;
        List<VehTypeTendencyStats> vehicleTypeStatsList=new ArrayList<>();
        Map<String,Object> resultMap=new HashMap<>();
        if(vo.getTendencyStatType()==0){
            tendencyStatsList=detectRecordMapper.queryTendencyStats(vo);
            //总览大屏上的趋势,或单个车型检测趋势
            if(vo.getOverParamType()==1){//如果是统计全部,将超限的也一起统计,值为number2
                tendencyStatsList=detectRecordMapper.queryTendencyStats(vo);
                short overParamType=3;
                vo.setOverParamType(overParamType);//总重超限
                List<TendencyStats> tendencyStatsList2=detectRecordMapper.queryTendencyStats(vo);
                for(TendencyStats item:tendencyStatsList){
                    for(TendencyStats item2:tendencyStatsList2){
                        if(item.getDetectDate().equals(item2.getDetectDate())){
                            item.setNumber2(item2.getNumber());
                        }
                    }
                }
            }
        }else if(vo.getTendencyStatType()==1){//每个车型检测趋势
            tendencyStatsList=detectRecordMapper.queryTendencyStats2(vo);

            Map<String, List<TendencyStats>> dateGroupMap = tendencyStatsList.stream().collect(Collectors.groupingBy(t -> t.getDetectDate(), Collectors.toList()));
            Set<String> keySet=dateGroupMap.keySet();
            for(String date:keySet){
                List<TendencyStats> innerTendencyStats=dateGroupMap.get(date);
                VehTypeTendencyStats vehTypeTendencyStats=new VehTypeTendencyStats();
                vehTypeTendencyStats.setDetectDate(date);
                for(TendencyStats item:innerTendencyStats){
                    switch (item.getVehicleType()){
                        case 12:
                            vehTypeTendencyStats.setVehType12Num(item.getNumber());
                            break;
                        case 2:
                            vehTypeTendencyStats.setVehType2Num(item.getNumber());
                            break;
                        case 3:
                            vehTypeTendencyStats.setVehType3Num(item.getNumber());
                            break;
                        case 4:
                            vehTypeTendencyStats.setVehType4Num(item.getNumber());
                            break;
                        case 5:
                            vehTypeTendencyStats.setVehType5Num(item.getNumber());
                            break;
                        case 6:
                            vehTypeTendencyStats.setVehType6Num(item.getNumber());
                            break;
                        case 7:
                            vehTypeTendencyStats.setVehType7Num(item.getNumber());
                            break;
                        case 8:
                            vehTypeTendencyStats.setVehType8Num(item.getNumber());
                            break;

                    }
                }
                vehicleTypeStatsList.add(vehTypeTendencyStats);
            }
        }
        resultMap.put("tendencyStatsList",tendencyStatsList);
        resultMap.put("vehicleTypeStatsList",vehicleTypeStatsList);
        return resultMap;
    }

    @Override
    public List<OverRangeStats> overRangeStats(DetectStatsQueryParam vo) {
        Double overDetectTotal=0.0;
        List<OverRangeStats> overRangeStatsList = detectRecordMapper.queryOverRangeStats(vo);
        for(OverRangeStats overRangeStats:overRangeStatsList){
            overDetectTotal+=overRangeStats.getRangeNum();
        }
        for(OverRangeStats overRangeStats:overRangeStatsList){
            overRangeStats.setRangeRatio(NumberUtil.halfUp(overRangeStats.getRangeNum()/overDetectTotal*100,2));
        }
        return overRangeStatsList;
    }

    @Override
    public List<BelongAddrStats> belongAddrStats(DetectStatsQueryParam vo) {
        List<BelongAddrStats> belongAddrStatsList = detectRecordMapper.queryBelongAddrStats(vo);
        for(BelongAddrStats belongAddrStats:belongAddrStatsList){
            belongAddrStats.setOverRatio(NumberUtil.halfUp(belongAddrStats.getOverNum()/belongAddrStats.getDetectNum()*100,2));
        }
        return belongAddrStatsList;
    }

    @Override
    public List<DetectPointDetectStats> queryDetectPointStats(DetectStatsQueryParam vo) {
        List<DetectPointDetectStats> detectPointDetectStatsList = detectRecordMapper.queryDetectPointStats(vo);
        Map<String, List<DetectPointDetectStats>> dateGroupMap = detectPointDetectStatsList.stream().collect(Collectors.groupingBy(t -> t.getDetectPointId(), Collectors.toList()));
        List<DetectPointDetectStats> resultList=new ArrayList<>();
        Set<String> pointSet=dateGroupMap.keySet();
        for(String pointId:pointSet) {
            List<DetectPointDetectStats> innerTendencyStats = dateGroupMap.get(pointId);
            DetectPointDetectStats resultItem = new DetectPointDetectStats();
            resultItem.setDetectPointId(pointId);
            Long pointDetectNum=0l;
            for (DetectPointDetectStats item : innerTendencyStats) {
                resultItem.setDetectPointName(item.getDetectPointName());
                if(item.getOverFlag()==1){//超限
                    resultItem.setOverNum(item.getNum());
                }
                pointDetectNum+=item.getNum();
            }
            resultItem.setDetectNum(pointDetectNum);
            if(innerTendencyStats!=null && innerTendencyStats.size()>0){
                DetectPointDetectStats oneStatsItem=innerTendencyStats.get(0);
                BeanUtils.copyProperties(oneStatsItem,resultItem,"detectNum","overNum");
                resultItem.setOnlineDurationStr(DateUtils.convertSecondsToHMS(oneStatsItem.getOnlineDuration()));
                float total=resultItem.getDetectNum();
                if(resultItem.getOverNum()!=null){
                    resultItem.setOverRatio(NumberUtil.halfUp(resultItem.getOverNum()/total*100,2));
                }
            }
            resultList.add(resultItem);
        }
        return resultList;
    }


    @Override
    public  DetectPointStats queryPointStats(DetectStatsQueryParam vo) {
        List<PointStatsVo> pointStatsVoList = detectRecordMapper.queryPointStats(vo);
        DetectPointStats detectPointStats=new DetectPointStats();
        for(PointStatsVo item : pointStatsVoList){
            if(item.getStatus()!=null && item.getStatus()==1) {//在线
                detectPointStats.setOnlineTotal(item.getNum());
            }else{
                detectPointStats.setOfflineTotal(item.getNum());
            }
        }
        detectPointStats.setTotal(detectPointStats.getOfflineTotal()+detectPointStats.getOnlineTotal());
        double temp=detectPointStats.getOfflineTotal()+detectPointStats.getOnlineTotal();
        detectPointStats.setOnlineRatio(NumberUtil.halfUp(detectPointStats.getOnlineTotal()/temp*100,2));
        Long detectTotal = detectRecordMapper.queryDetectTotal(vo);
        Long overTotal = detectRecordMapper.queryOverTotal(vo);
        detectPointStats.setDetectNum(detectTotal);
        detectPointStats.setOverNum(overTotal);
        return detectPointStats;
    }
}
